Automated Presentation of directory src/swtools/gencall/

HUB | Up | Download | Pheedbak | Tree | Topic | A-Z | Search | Hot | New


Please be aware: what appears below are the v4.2 DT bits in auto-generated html form.
As we have the time, we will update these to reflect the current "state of the world".


README file from "gencall" directory

	        ~4Dgifts/toolbox/src/swtools/gencall README


				    Created by Gianni Mariani  5-Dec-1993

DISCLAIMER :

This is unsupported code and is intended as an example only. Silicon
Graphics may change interface at any time that may render this code
example inoperable. This code has also not been tested extensivly so
you may find bugs. Silicon Graphics is making no expression of warranty
by publishing this code and documentation. In simple words - you use it
you take the full responsibility of that action.  Any enhancements and
bug fixes you may wish to send me can be emailed to gianni@neu.sgi.com
however I may not acknowledge it.

README :

Preface -

Machine code generated by high level languages abide by a "calling
convention".  The "calling convention" is basically a set of
assumptions made by the compiler about where function arguments will be
found on entry to a function.  The MIPS calling convention uses
registers to pass the first few arguments and is dependant on what
type/float or otherwise is being passed.  The "calling convention" also
makes assumptions about where values are returned.  By far the simplest
and most portable way to call a function is to simply write a function
call in a high level language.  However, for programs that do not know
at the time of compilation what arguments are being passed like
interpreters or dynamically loaded code, it is difficult to call
functions whose specification (return value and arguments) is only
known at the time of execution.

Description -

The following list of files generates a high level programming interface
to the MIPS calling convention on SGI machines.  This allows a programmer
to call any function specified by a call descrption at run time.  This
can be used by programs that do not know what the call interface is at
compile time.

List of files:

    Makefile	    : makes the test executable genctest
    README	    : this.
    gencall.h	    : header for these functions
    gencall.s	    : assembly level routines
    gencif.c	    : high level interface
    genctest.c	    : test code


The interface is in two layers.  Low level (assembler) and high level
(call interface).

The assebler level implements the minimum that is required in assembler.
The assebler level simply creates an argument list area on the stack and
then calls a function to copy the related data onto the stack and then
calls the function in question,  it will then deposit return values into
the appropriate return buffer if given.  This is done in assembler since
it is obvious that it is impossible to manipulate the stack at whim in
a high level language.  This is basically self contained in gencall.s.

Low level example :

CallFromGeneralArgs is the function that effects the low level interface.
In the case below it calls memcpy to generate the arguments stack
made up of the arguments in args.  The data is basically copied into
the args buffer created by CallFromGeneralArgs and then calling printf.


static int	args[] = {
    { (int) "Arg1=%d Arg2=%s Arg3=%d Arg4=%s \n" },
    { 5 },
    { (int) "This is arg2" },
    { 6 },
    { (int) "This is arg4" },
};

main()
{
    extern memcpy();
    extern printf();
    
    CallFromGeneralArgs(
	memcpy,
	args,
	sizeof( args ),
	0,
	0,
	printf
    );
}

High level description :

gencif.c implements the high level interface.  The GCIF_CALLDESC struct
encapsulates all the required information to create an argument list.
Typically one would generate an arg list and return value spec from an
external interface like an interpreter or a DSO interface file or such.
This would be used to generate the args list and the return information.
gcif_filldesc would then be called to evaluate the gcif_bytes and
gcif_flags values that are used by the assembler level routines. At the
time of call, the values of arguments are placed in the call descripion
( gcif_argv, gcif_nargv and gcif_retv ) and together with the address
of the function, gcif_call is called which will effect the call to the
address given.

High level example:

The following example shows how to structs as well as giving an example
of the high level interface.  The structure typed "as" is passed as
the first argument as well as being the return value's type. "scd" is
initialized to contain the args being passed and the return value.
gcif_filldesc is called to initialize the gcif_bytes and gcif_flags
fields.  This need only be done once after the args and return value
are defined.  The arguments are initialized and then gcif_call is
used to perform the call to "as_SFI".


/* structure passing example						*/

typedef struct {
    char    val[23];
} as;

GCIF_ARG	sargs[] = {
{
    gcif_struct,    /* GCIF_ETYPE	gcif_type : 8;			*/
    4,		    /* unsigned		gcif_align : 8;			*/
    sizeof(as),	    /* unsigned		gcif_size : 16;			*/
},
{
    gcif_float,	    /* GCIF_ETYPE	gcif_type : 8;			*/
    4,		    /* unsigned		gcif_align : 8;			*/
    4,		    /* unsigned		gcif_size : 16;			*/
},
{
    gcif_int,	    /* GCIF_ETYPE	gcif_type : 8;			*/
    4,		    /* unsigned		gcif_align : 8;			*/
    4,		    /* unsigned		gcif_size : 16;			*/
},
};

GCIF_CALLDESC	scd[1] = {
    /* GCIF_ARG	      * gcif_args;	* args				*/
    /* unsigned		gcif_nargs;	* number of args		*/
    sargs, sizeof( sargs ) / sizeof( * sargs ),

    gcif_struct,	/* GCIF_ETYPE	        gcif_rettype;		*/
    sizeof( as ),	/* unsigned		gcif_retsize;		*/
    
    0,			/* unsigned		gcif_bytes;		*/
    0,
    /* GCIF_MKFLAGS( gcif_double, FP_PASS( gcif_double, gcif_float ) ), */
			/* unsigned		gcif_flags;		*/

    /* void	     ** gcif_argv;	* arg value pointers		*/
    /* int		gcif_nargv;	* number of value pointers	*/
    ARYNI( sargv ),

    /* void	      * gcif_retv;	* Return value			*/    
};

as as_SFI( as a, float b, int i )
{
    printf( "as_SFI %s %f %d\n", a.val, b, i );
    return a;
}

example_struct()
{
    double	    retval;
    float	    arg2;
    int		    i;
    as		    s;
    as		    s1;
    void	  * sargv[3];
    
    gcif_filldesc( scd );
    
    sargv[ 0 ] = ( void * ) & s;
    sargv[ 1 ] = ( void * ) & arg2;
    sargv[ 2 ] = ( void * ) & i;

    scd->gcif_retv = ( void * ) & s1;
    scd->gcif_argv = sargv;
    scd->gcif_nargv = 3;

    strcpy( s.val, "Hello world" );
    arg2 = 122.7;
    i = 29;

    gcif_call( as_SFI, scd );

    printf( "as_SFI returns %s\n", s1.val );
}

MAN PAGE:

NAME
    gencall - generalized call interface

C SPECIFICATION

	#include <gencall.h>

	int CallFromGeneralArgs(
	    void	( * Prefunc )( void *, void *, unsigned, unsigned * ),
	    void          * args,
	    unsigned        bytes,
	    unsigned        flags,
	    void          * retval,
	    GCIF_FUNC_T     func
	);
	
	void	gcif_filldesc(
	    GCIF_CALLDESC	* args
	);
	
	int gcif_call(
	    GCIF_FUNC_T	    * func,
	    GCIF_CALLDESC   * args
	);
	
	void gcif_Prefunc(
	    char	    * call_args,
	    GCIF_CALLDESC   * args,
	    int		      bytes,
	    unsigned	    * flags_p
	);

	typedef struct  GCIF_CALLDESC {
	    GCIF_ARG	      * gcif_args;	/* args			*/
	    unsigned		gcif_nargs;	/* number of args	*/
	    GCIF_ETYPE	        gcif_rettype;	/* return type		*/
	    unsigned		gcif_retsize;	/* return size (for structs)*/
	    /* Filled in by gcif_filldesc if called.			*/
	    unsigned		gcif_bytes;	/* Bytes required for args*/
	    unsigned		gcif_flags;	/* gencall flags	*/
	    /* Filled in by user just before being called		*/
	    void	     ** gcif_argv;	/* arg value pointers	*/
	    int			gcif_nargv;	/* number of value pointers*/
	    void	      * gcif_retv;	/* Return value		*/	
	} GCIF_CALLDESC;

PARAMETERS

    func	address of function to call

    Prefunc	address of function to prepare arguments.  The first
		argument to Prefunc is the pointer to the args to func.
		The second is the one given to CallFromGeneralArgs, the
		third is bytes and the fourth is a pointer to flags.

    args	Pointer passed to Prefunc to be used to prepare args
		before calling func.  For gcif_Prefunc, gcif_filldesc
		and gcif_call, args is a call descriptor.

    flags	Used by CallFromGeneralArgs to determine which registers
		to load for passing by registers as well as which
		register contains the return value.  All values can
		be generated by the GCIF_MKFLAGS and FP_PASS macros.
		Only the first two parameters determine the passing
		convention needed.  The return value is simply a type
		specifier in the GCIF_ETYPE enum.

    retval	Pointer to the return value.

    flags_p	Pointer to the flags parameter passed to CallFromGeneralArgs.

    call_args	Pointer to arguments frame for function call.

DESCRIPTION

    CallFromGeneralArgs will set up the appropriate argument frame for
    calling any function.  This is usefull in interpreters or if call
    parameters are determined at run time as may be the case if an
    application is supplied by a DSO. It does not read any values pointer
    to by the args parameter, however it passes this to the argument
    preparation function.  CallFromGeneralArgs will also write the return
    value from the function call to the memory pointed to by retval. 
    Functions that have return values as structs do not use the retval
    pointer, however they expect the return value's address as the
    first 'conventional' argument.  This must always be a valid pointer.
    If you use gcif_call, it will take care of struct return values.

    gcif_filldesc will generate values in the gcif_bytes and gcif_flags
    fields.  These need only be called once after the arguments and
    return value description is completed.

    gcif_call will call the function pointed to by func with the
    arguments as described in the call descriptor pointed to by args.
    It will correctly call functions returning struct if the return
    value pointer is nil.  It calls CallFromGeneralArgs and uses
    gcif_Prefunc as a preparation func.

    gcif_Prefunc is intended to be called from CallFromGeneralArgs as a
    preparation function.  It will copy the arguments described in the
    GCIF_CALLDESC structure pointed to by args onto a arguments frame
    pointed to by call_args.

DIAGNOSTICS

    None.

BUGS

    None known.

Files of interest from "src/swtools/gencall" directory

Source

Documentation

Reference


Select any combo of files you'd like to send yourself a compressed tar image of. Executables/scripts are indicated with a trailing `*' character. (Depending upon the browser, it may be necessary to hold down the Ctrl key to select/deselect disjoint items.) a compressed tar image of the above-selected items.
OR, ...
a compressed tar image of the entire gencall directory.

Copyright © 1995, Silicon Graphics, Inc.